﻿using System.Collections.Generic;
using System.Globalization;
using DotNetNuke;
using Ventrian.NewsArticles;
using System;
using DotNetNuke.Entities.Modules;

namespace Aricie.DNN.Services.Url.FriendlyUrl.Providers.DNN6
{
    public class VentrianNewsArticlesUrlRewriter: IUrlRewriterProvider, IIsActive
    {

        class VentrianNewsArticleHelper
        {

            private static Object lockForListOfModulesIdByCategory = new Object();
            private static Dictionary<int, int> _modulesIdByCategory = new Dictionary<int, int>();

            private static Dictionary<int, int> ModulesIdByCategory
            {
                get
                {
                    lock (lockForListOfModulesIdByCategory)
                    {
                        if (_modulesIdByCategory.Count == 0)
                        {
                            foreach (int moduleId in getNewsArticleModuleIds())
                            {
                                CategoryController objCC = new CategoryController();
                                List<CategoryInfo> categoriesList = objCC.GetCategoriesAll(moduleId, -1);
                                foreach (CategoryInfo category in categoriesList)
                                {
                                    if (!_modulesIdByCategory.ContainsKey(category.CategoryID))
                                    {
                                        _modulesIdByCategory.Add(category.CategoryID, moduleId);
                                    }
                                }
                            }
                        }
                    }
                    return _modulesIdByCategory;
                }
            }

            private static void AddCategoryAndModuleId(int categoryId)
            {
                foreach (int moduleId in getNewsArticleModuleIds())
                {
                    CategoryController objCC = new CategoryController();
                    CategoryInfo searchedCategory = objCC.GetCategory(categoryId, moduleId);
                    if (searchedCategory != null)
                    {
                        _modulesIdByCategory.Add(searchedCategory.CategoryID, moduleId);
                        break;
                    }
                }
            }

            public static int GetModuleIdFromCategoryId(int categoryId)
            {
                int moduleId = -1;
                if (!ModulesIdByCategory.TryGetValue(categoryId,out moduleId))
                {
                    AddCategoryAndModuleId(categoryId);
                    return ModulesIdByCategory[categoryId];
                }
                return moduleId;
            }

            private static List<int> getNewsArticleModuleIds()
            {
                List<int> newsArticleModuleIds = new List<int>();

                DotNetNuke.Entities.Modules.ModuleController objMC = new DotNetNuke.Entities.Modules.ModuleController();
                foreach (ModuleInfo module in objMC.GetModulesByDefinition(0, "DnnForge - NewsArticles"))
                {
                    if (!newsArticleModuleIds.Contains(module.ModuleID))
                    {
                        newsArticleModuleIds.Add(module.ModuleID);
                    }
                }

                return newsArticleModuleIds;
            }

        }

        private static List<string> ValidArticleTypes = new List<string> (){ "archives", "approvearticles", "approvecomments", "articleview", "archiveview", "authorview", "categories", "categoryview", "editcomment", "editpage", "editpages", "editsortorder", "myarticles", "notauthenticated", "notauthorized", "search", "submitnews", "submitnewscomplete", "syndication", "tagview" };


        List<GroupParamsRewrite> IFriendlyUrlGroupProvider.GetRewrites()
		{
			List<GroupParamsRewrite> toReturn = new List<GroupParamsRewrite>();
			string desc = "Title of the current Article, filtered according to the general parameters";
            toReturn.Add(new GroupParamsRewrite("ArticleTitle", desc, RewriteType.SubPath, UrlParam.FromSyntax("articleType"), UrlParam.FromSyntax("articleid")));
			desc = "Name of the current Ventrian NewsArticle Article's category, filtered according to the general parameters";
            toReturn.Add(new GroupParamsRewrite("CategoryName", desc, RewriteType.SubPath, UrlParam.FromSyntax("articleType"), UrlParam.FromSyntax("categoryid")));
			desc = "Title of the current Ventrian NewsArticle Article's Page being browsed, filtered according to the general parameters";
            toReturn.Add(new GroupParamsRewrite("PageTitle", desc, RewriteType.SubPath, UrlParam.FromSyntax("articleType"), UrlParam.FromSyntax("pageid")));
			return toReturn;
		}

        GroupRewriteResult IUrlRewriterProvider.RewriteParams(string groupName, RewriteType objRewriteType, Dictionary<UrlParam, string> parameters, FriendlierUrlStrategy behaviour)
		{
			GroupRewriteResult toReturn = new GroupRewriteResult();

			if (parameters.Count > 0)
			{
			    string articleType = parameters[UrlParam.FromSyntax("articleType")].ToLowerInvariant();
			    if (!ValidArticleTypes.Contains(articleType))
			    {
			        throw new ApplicationException(string.Format("Invalid article type {0} for ventrian Newsarticle", articleType));
			    }
				switch (groupName.ToLowerInvariant()) {
					case "articletitle":
                        int articleId = int.Parse(parameters[UrlParam.FromSyntax("articleid")], CultureInfo.InvariantCulture);
						toReturn.RewriteValue = GetArticleTitle(articleId, behaviour);
						toReturn.ConsumedParameters[UrlParam.FromSyntax("articleid")] = true;
                        toReturn.ConsumedParameters[UrlParam.FromSyntax("articleType")] = true;
						break;
					case "categoryname":
						int categoryId = int.Parse(parameters[UrlParam.FromSyntax("categoryid")], CultureInfo.InvariantCulture);
                        toReturn.RewriteValue = GetCategoryName(categoryId, VentrianNewsArticleHelper.GetModuleIdFromCategoryId(categoryId), behaviour);
						toReturn.ConsumedParameters[UrlParam.FromSyntax("categoryid")] = true;
                        toReturn.ConsumedParameters[UrlParam.FromSyntax("articleType")] = true;
						break;
					case "pagetitle":
						int pageId = int.Parse(parameters[UrlParam.FromSyntax("pageid")], CultureInfo.InvariantCulture);
						toReturn.RewriteValue = GetPageTitle(pageId, behaviour);
						toReturn.ConsumedParameters[UrlParam.FromSyntax("pageid")] = true;
                        toReturn.ConsumedParameters[UrlParam.FromSyntax("articleType")] = true;
						break;
				}
			}
			return toReturn;
		}


		public string GetArticleTitle(int articleId, FriendlierUrlStrategy behaviour)
		{
			ArticleController controller = new ArticleController();
			ArticleInfo objArt = controller.GetArticle(articleId);
			string toReturn = "";
			if (objArt != null) {
				toReturn = objArt.Title;
			}
			//Return behaviour.StringEscaper.EscapeString(toReturn)
			return toReturn;
		}

        public string GetCategoryName(int categoryId, int moduleId, FriendlierUrlStrategy behaviour)
		{
			CategoryController controller = new CategoryController();
			CategoryInfo objCat = controller.GetCategory(categoryId, moduleId);
			string toReturn = "";
			if (objCat != null) {
				toReturn = objCat.Name;
			}
			return toReturn;
		}

		public string GetPageTitle(int pageId, FriendlierUrlStrategy behaviour)
		{
			PageController controller = new PageController();
			PageInfo objPage = controller.GetPage(pageId);
			string toReturn = "";
			if (objPage != null) {
				toReturn = objPage.Title;
			}
			return toReturn;
		}

		public bool IsActive {
			get { return DotNetNuke.Framework.Reflection.CreateType("Ventrian.NewsArticles.CategoryController, Ventrian.NewsArticles", true) != null; }
		}


    }
}
